This section includes an introduction to the project motivation, data, and research question. Describe the data and definitions of key variables.
It should also include some exploratory data analysis.
All of the EDA won’t fit in the paper, so focus on the EDA for the response variable and a few other interesting variables and relationships.
Project Motivation
1999 wurde in der Forschung (Collins et al.) ermittelt, dass die ASA-Klassifizierung des körperlichen Zustands, das Alter, Bluttransfusionen während der Operation und die Dauer von Operationen einen Aufschluss darüber geben, ob der Krankenhausaufenthalt des Patienten länger als gewöhnlich ausfallen wird. Des Weiteren gibt es zahlreiche Studien, bspw. die Forschung von Biber et al. (2012), Singler et al. (2013) oder Ogliari et al. (2022) die festgestellt haben, dass es eine Korrelation zwischen dem Alter von Patienten und der Verweildauer in Notaufnahmen gab. Dieser Frage möchten wir gerne nachgehen und versuchen, die Aufenthaltsdauer vorherzusagen
Data
Uns liegen Daten von nicht-kardiochirurgischen Patienten vor, welche sich von August 2016 bis Juni 2017 einer Routine- oder Notoperation am Seoul National University Hospital, Seoul, Korea, unterzogen. Von den 7.051 in Frage kommenden Fällen wurden Fälle mit lokaler Anästhesie (239), unvollständiger Aufzeichnung (279) und Verlust von wesentlichen Datenspuren (145) ausgeschlossen. Schließlich wurden 6.388 Fälle (91 %), die eine Allgemeinanästhesie, Spinalanästhesie und Sedierung/Analgesie erhielten, in den Datensatz aufgenommen. Der Datensatz besteht aus intraoperativen Vitaldaten und perioperativen klinischen Informationen von 6.388 Fällen. Die Vitaldaten umfassen bis zu 12 Wellenform- und 184 numerische Datenspuren, die von mehreren Anästhesiegeräten erfasst wurden, die den Patienten während der Operation eingesetzt wurden. Die Daten wurden nicht vorverarbeitet, da das reale Rauschen in den Vitaldaten für die Entwicklung praktischer Überwachungsalgorithmen sehr wichtig ist. Insgesamt 74 perioperative klinische Informationsparameter und 34 Zeitreihen perioperativer Laborergebnisse werden zur Verfügung gestellt, um die Interpretation der Beziehung zu den intraoperativen Vitalzeichen zu erleichtern.
Research Question
Wir stellen uns die Frage, welche dem Krankenhaus vorliegenden Daten die Aufenthaltsdauer von Patienten beeinflusst. Da der Datensatz des Seoul National University Hospital (Seoul, Korea) eine,Vielzahl von möglichen Variablen enthält werden wir uns vorerst auf den Zusammenhang zwischen dem Alter der Patienten und der Behandlungsdauer beschäftigen.
Wir berechnen eine weitere Variable “op_duartion”. Sie zeigt die Dauer einer Operation an. Dafür subtrahieren wir von der Variablen “opend” die Variable “opstart”.
Code
df['op_duration']=df['opend']-df['opstart']
Wir benennen einige Variablen um: “caseend” bezeichnet das Ende eines Falls, vom Startpunkt 0, daher bennen wir diese Variable “record_duration” Die Variable “icu_days” bezeichnet die Aufenthaltsdauer im Krankenhaus (icu), daher bennen wir diese Variable “length_of_stay” Da wir uns unter der Variable “intraop_ebl” wenig vorstellen konnten, benennen wir diese in “estimated_blood_loss” um.
Die Spalte ‘age’ enthält u.a. die Zeichen “>89” und “0.7”. Daher wird das Größer-als-Zeichen entfernt und die Werte gerundet, damit es zu int umwandelt werden kann.
print("Missing values in 'estimated_blood_loss':",df['estimated_blood_loss'].isnull().sum())print("Missing values in 'op_duration':",df['op_duration'].isnull().sum())print("Missing values in 'length_of_stay':",df['length_of_stay'].isnull().sum())print("Missing values in 'bmi':",df['bmi'].isnull().sum())print("Missing values in 'asa':",df['asa'].isnull().sum())print("Missing values in 'age':",df['age'].isnull().sum())print("Missing values in 'recording_duration':",df['recording_duration'].isnull().sum())
Missing values in 'estimated_blood_loss': 0
Missing values in 'op_duration': 0
Missing values in 'length_of_stay': 0
Missing values in 'bmi': 0
Missing values in 'asa': 133
Missing values in 'age': 0
Missing values in 'recording_duration': 0
Lediglich die Spalte ‘asa’ hat 133 NAs. Diese werden durch den Median der Spalte ersetzt.
Code
df['asa'] = df['asa'].fillna(df['asa'].median())
Wir prüfen, ob der Vorgang korrekt durchgeführt wurde.
Code
df['asa'].isnull().sum()
0
Methodology
REMOVE THE FOLLOWING TEXT
This section includes a brief description of your modeling process.
Explain the reasoning for the type of model you’re fitting, predictor variables considered for the model.
Additionally, show how you arrived at the final model by describing the model selection process, variable transformations (if needed), assessment of conditions and diagnostics, and any other relevant considerations that were part of the model fitting process.
Aufgrund unserer Projektmotivation heraus nutzen wir die dort erwähnten Variablen. Zusätzlich nehmen wir noch die Variable “bmi” hinzu. Diese wird zwar nicht erwähnt, zeigt jedoch auf eine andere Art als die ASA-Klassifizierung (Variable “asa”) auch den Körperlichen Zustand eines Patienten. Aus der Projektmotivation ist auch zu entnehmen, dass wir die Krankenhausaufenhaltsdauer anhand dieser Prädiktoren bestimmen möchten.
Variablen
Code
#Hier kann man auch ggf. emop und department wieder heraus nehmendf=df[['recording_duration','age','asa','bmi','length_of_stay','op_duration','estimated_blood_loss','emop','department']]y_label ='length_of_stay'features = ['recording_duration','age','asa','bmi','op_duration','estimated_blood_loss']X = df[features]y = df[y_label]
Code
#Das kann man ggf. raus löschen, nur falls man sich die unterschiedlichen Abteilungen anschauen möchte, muss man dann aber auch mind. noch bei der Punktewolke mit aufnehmenalt.Chart(df).mark_bar().encode( alt.X(alt.repeat("column"), type="nominal", bin=True), y='count()',).properties( width=150, height=150).repeat( column=['department'])
Code
#Das kann man auch ggf. raus löschen nur falls man sich die Notoperationen anschauen möchte, muss man dann aber auch mind. noch bei der Punktewolke mit aufnehmenhist = alt.Chart(df).mark_bar().encode( x=alt.X("emop", bin=alt.BinParams(maxbins=2), scale=alt.Scale(zero=True)), y='count()',)hist
Wir möchten uns nun die Daten einmal einzeln anschauen
Wir können eine starke Interkorrelation zwischen op-duration und recording_duration erkennen. Die Korrelation der Prädiktoren mit der Variablen “length_of_stay” ist sehr gering. Wir schauen uns dies nochmal mit Hilfe einer Punktewolke an:
Nun teilen wir den Datensatz in einen Trainings- und einen Testdatensatz auf
Code
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
Lineare Regression
Wir beginnen nun ein Regressionsmodell aufzustellen
Code
reg = LinearRegression()
Nun erstellen wir die Kreuzvalidierung der Daten mit 5 Folds
Code
scores = cross_val_score(reg, X_train, y_train, cv=5, scoring='neg_mean_squared_error') *-1# store cross-validation scoresdf_scores = pd.DataFrame({"lr": scores})# reset index to match the number of foldsdf_scores.index +=1alt.Chart(df_scores.reset_index()).mark_line( point=alt.OverlayMarkDef()).encode( x=alt.X("index", bin=False, title="Fold", axis=alt.Axis(tickCount=5)), y=alt.Y("lr", aggregate="mean", title="Mean squared error (MSE)"))
Im nächsten Schritt trainieren wir das Modell
Code
reg.fit(X_train, y_train)
LinearRegression()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
LinearRegression()
Wir lassen uns nun die Regressionsgerade unsereres Modells berechnen
Code
intercept = pd.DataFrame({"Name": ["Intercept"],"Coefficient":[reg.intercept_]} )# make a slope tableslope = pd.DataFrame({"Name": features,"Coefficient": reg.coef_})# combine estimates of intercept and slopestable = pd.concat([intercept, slope], ignore_index=True, sort=False)round(table, 3)
Nun möchten wir prüfen, ob unser Modell mit weniger Variablen besser wird, da beispielsweise eine starke Interkorrelation zwischen op-duarion und recording_duration erkennen. Wir nutzen dafür die Vorwärtseliminierung, daher betrachten wir zuerst wie wichtig welche Variable für unser Modell ist. Wir werden im Anschluss unser Modell der Reihe nach mit den wichtigsten Variablen aufbauen und das “Adjusted R²” berechnen, bis dieses nicht mehr besser wird.
Es scheint so, als wäre das Modell mit allen Prediktoren, außer der Variable “recording_duration” das mit der höchsten Güte. Um sicher zu gehen, lassen wir dennoch das Modell mit allen Prediktoren noch einmal berechnen.
Beim Modell mit allen Prediktoren zeigt sich ein kleineres adjusted R² also beim Modell ohne “recording_duration”, daher ist das Modell ohne “recording_duration” das mit höchster Güte.
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
LassoCV(cv=5, random_state=0)
Code
reg.alpha_
0.00129766876509997
Code
# Fit the model to the complete training dataregla = Lasso(alpha=reg.alpha_)regla.fit(X_train, y_train)
Lasso(alpha=0.00129766876509997)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
Lasso(alpha=0.00129766876509997)
Code
# interceptintercept = pd.DataFrame({"Name": ["Intercept"],"Coefficient":[reg.intercept_]} )# make a slope tableslope = pd.DataFrame({"Name": features,"Coefficient": reg.coef_})# combine estimates of intercept and slopestable = pd.concat([intercept, slope], ignore_index=True, sort=False)round(table, 3)
This is where you will output the final model with any relevant model fit statistics.
Describe the key results from the model. The goal is not to interpret every single variable in the model but rather to show that you are proficient in using the model output to address the research questions, using the interpretations to support your conclusions.
Focus on the variables that help you answer the research question and that provide relevant context for the reader.
In this section you’ll include a summary of what you have learned about your research question along with statistical arguments supporting your conclusions. In addition, discuss the limitations of your analysis and provide suggestions on ways the analysis could be improved. Any potential issues pertaining to the reliability and validity of your data and appropriateness of the statistical analysis should also be discussed here. Lastly, this section will include ideas for future work.
In den Variablen erkennen wir, dass unsere Vorhersagevarible length_of_stay eine sehr große Streuung besitzt. Wir sehen eine Kollinearität zwischen den Variablen op_duration und recording_duration.
Lineares Regressionsmodell:
Den größten Einfluss auf unser Modell hat die Variable der ASA-Klassifikation.
Unser Modell wird nicht besser, wenn wir eine der verwendeten Variablen ausschließen.
Wir sehen ein kleines R² unseres Modells, was eine geringe Güte des Modells bedeutet. Etwa 18% der Variabilität der Aufenthaltsdauer wird durch das Modell erklärt. Des Weiteren zeigt der mean squared error der einzelnen Folds, dass es sich um kein sehr stabiles Modell handelt.
Lasso Regressionsmodell:
Wir sehen ein kleines R² unseres Modells, was eine geringe Güte des Modells bedeutet. Die Güte ist sogar noch etwas unter der des linearem Regressionsmodells. Etwa 11,8% der Variabilität der Aufenthaltsdauer wird durch das Modell erklärt. Anhand des bereinigten R² sehen wir, das lineare Regressionsmodell ist dem Lasso Regressionsmodell gegenüber zu bevorzugen.
Auch der mean squared error, root mean squared error und der mean absolute error fallen höher, und somit schlechter aus als beim linearen Regressionsmodell. Auch dies weißt darauf hin, dass das lineare Regressionsmodell dem lasso Regressionsmodell zu bevorzugen ist.